// RecordService.h

#ifndef _RECORDSERVICE_h
#define _RECORDSERVICE_h

#include "Module.h"
#include "RecordModuleRequest.h"
#include "SPI.h"
#include "SD.h"
#include "FS.h"
#include "RecordEvent.h"

#define RECORD_MODULE_ID "RECORD"

///////////////////////for vs10xx///////////////////////////////////
#define VS_XRESET 21 
#define VS_DREQ   22
#define VS_XCS    2
#define VS_XDCS   5

/** VS10xx SCI Write Command byte is 0x02 */
#define VS_WRITE_COMMAND 0x02
/** VS10xx SCI Read Command byte is 0x03 */
#define VS_READ_COMMAND 0x03


#define SPI_MODE	0x0   /**< VS10xx register */
#define SPI_STATUS	0x1   /**< VS10xx register */
#define SPI_BASS	0x2   /**< VS10xx register */
#define SPI_CLOCKF	0x3   /**< VS10xx register */
#define SPI_DECODE_TIME	0x4   /**< VS10xx register */
#define SPI_AUDATA	0x5   /**< VS10xx register */
#define SPI_WRAM	0x6   /**< VS10xx register */
#define SPI_WRAMADDR	0x7   /**< VS10xx register */
#define SPI_HDAT0	0x8   /**< VS10xx register */
#define SPI_HDAT1	0x9   /**< VS10xx register */
#define SPI_AIADDR	0xa   /**< VS10xx register */
#define SPI_VOL		0xb   /**< VS10xx register */
#define SPI_AICTRL0	0xc   /**< VS10xx register */
#define SPI_AICTRL1	0xd   /**< VS10xx register */
#define SPI_AICTRL2	0xe   /**< VS10xx register */
#define SPI_AICTRL3	0xf   /**< VS10xx register */

#define SM_DIFF		0x01   /**< VS10xx register */
#define SM_JUMP		0x02   /**< VS10xx register */
#define SM_RESET	0x04   /**< VS10xx register */
#define SM_OUTOFWAV	0x08   /**< VS10xx register */
#define SM_PDOWN	0x10   /**< VS10xx register */
#define SM_TESTS	0x20   /**< VS10xx register */
#define SM_STREAM	0x40   /**< VS10xx register */
#define SM_PLUSV	0x80   /**< VS10xx register */
#define SM_DACT		0x100   /**< VS10xx register */
#define SM_SDIORD	0x200   /**< VS10xx register */
#define SM_SDISHARE	0x400   /**< VS10xx register */
#define SM_SDINEW	0x800   /**< VS10xx register */
#define SM_ADPCM        0x1000   /**< VS10xx register */
#define SM_ADPCM_HP     0x2000   /**< VS10xx register */

class RecordModule : public Module
{
private:
    RecordStatus state = RECORD_CLOSE;
    void record(char* recfile);
    void stop();
public:
    RecordModule() : Module(RECORD_MODULE_ID) {};
    void init();
    DataBusType getDataBusType() { return TYPE_SPI; };
    ModuleType getType() { return RECORD; };
    bool checkAlive();
	virtual bool accept(ModuleRequest& request);
	void accept(RecordModuleRequest& request);
    void setHeaderField(unsigned char *d, unsigned long n) {
        int i;
        for (i = 0; i<4; i++) {
            *d++ = (unsigned char)n;
            n /= 0x100;
        }
    }
public:
    static void selectControlBus(void) { digitalWrite(VS_XCS, LOW); }
    static void deselectControlBus(void) { digitalWrite(VS_XCS, HIGH); }
    static void selectDataBus(void) { digitalWrite(VS_XDCS, LOW); }
    static void deselectDataBus(void) { digitalWrite(VS_XDCS, HIGH); }
    static void putInReset(void) { digitalWrite(VS_XRESET, LOW); }
    static void releaseFromReset(void) { digitalWrite(VS_XRESET, HIGH); }
    static char readDREQ(void) { return digitalRead(VS_DREQ); }

    static void writeRegister(unsigned char addressbyte, unsigned int value);
    static unsigned int readRegister(unsigned char addressbyte); /** Read the 16-bit value of a VS10xx register */
    static void writeData(unsigned char *databuf, unsigned char = 32); //write 32 bytes to vs1053
    
    static void initRecord();

    static void reset(void); //reset for vs10xx
    static void softReset(void); /* Soft Reset of VS10xx (Between songs) */
    static void loadPlugin(const  unsigned short *plugin, int length);
};

#endif

